package com.miot.restapi.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.miot.domain.util.Constant;
import com.miot.domain.util.MIDeviceUtil;
import com.miot.domain.util.MIHomeUtil;
import com.miot.object.device.*;
import com.miot.restapi.config.CacheComponent;
import com.miot.restapi.util.DataResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @Author: zhangyanbin
 * @Date: 2019/1/26 17:58
 * @Version 1.0
 */
@RestController
@RequestMapping("device")
@Api(value = "device", description = "设备控制器")
public class MiotDeviceRestController {

    protected static Logger logger = LoggerFactory.getLogger(MiotDeviceRestController.class);

    @Autowired
    private CacheComponent cacheComponent;

    /**
     * 手机端-批量修改设备名称
     *
     * @param deviceVoList
     * @return
     */
    @PostMapping("/batchEdit")
    @ApiOperation(value = "修改设备名称", notes = "修改设备名称", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public CompletableFuture<DataResult> batchEdit(@RequestBody List<EditDeviceVo> deviceVoList) {
        return CompletableFuture.supplyAsync(() -> {
            logger.info("手机端-修改设备名称传入参数是->" + deviceVoList);
            deviceVoList.stream().forEach(e ->
            {
                Long roomId = e.getRoomId();
                Long controlId = e.getControlId();
                String deviceName = e.getDeviceName();
                String realDid = e.getReal_did();
                MIDeviceUtil.deviceRename(controlId, realDid, deviceName);
                JSONArray realDidArray = new JSONArray();
                realDidArray.add(realDid);
                MIHomeUtil.createDevToRoom(controlId, roomId, realDidArray.toJSONString());
                JSONArray roomList = MIHomeUtil.getHome(controlId).getJSONArray("homeInfo").getJSONObject(0).getJSONArray("roomlist");
                cacheComponent.putForExpire(Constant.PREFIX_CONTROL_HOME_ID, String.valueOf(controlId), roomList, 2592000);
            });

            return DataResult.ok("修改成功");
        });
    }

    /**
     * 手机端-修改名称并从某个房间删除设备
     *
     * @param deviceVo
     * @return
     */
    @PostMapping("/editAndDelete")
    @ApiOperation(value = "修改设备名称", notes = "修改设备名称", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public CompletableFuture<DataResult> editAndDelete(@RequestBody EditOrDeleteDeviceVo deviceVo) {
        return CompletableFuture.supplyAsync(() -> {
            logger.info("手机端-修改设备名称传入参数是->" + deviceVo);
            Long controlId = deviceVo.getControlId();
            String realDid = deviceVo.getReal_did();
            long newRoomId = deviceVo.getNewRoomId();
            long oldRoomId = deviceVo.getOldRoomId();
            String deviceName = deviceVo.getDeviceName();
            JSONArray realDidArray = new JSONArray();
            realDidArray.add(realDid);
            if (newRoomId == oldRoomId) {
                MIDeviceUtil.deviceRename(controlId, realDid, deviceName);
            } else {
                if (oldRoomId == 0 && newRoomId != 0) {
                    MIHomeUtil.createDevToRoom(controlId, newRoomId, realDidArray.toJSONString());
                    MIDeviceUtil.deviceRename(controlId, realDid, deviceName);
                } else if (oldRoomId != 0 && newRoomId == 0) {
                    MIHomeUtil.deleteDevFromRoom(controlId, oldRoomId, realDid);
                    MIDeviceUtil.deviceRename(controlId, realDid, deviceName);
                }
            }
            JSONArray roomList = MIHomeUtil.getHome(controlId).getJSONArray("homeInfo").getJSONObject(0).getJSONArray("roomlist");
            cacheComponent.putForExpire(Constant.PREFIX_CONTROL_HOME_ID, String.valueOf(controlId), roomList, 2592000);
            return DataResult.ok("修改成功");
        });
    }

    /**
     * 手机端-删除房间设备
     *
     * @param deviceVo
     * @return
     */
    @PostMapping("/deleteDevFromRoom")
    @ApiOperation(value = "删除房间设备", notes = "删除房间设备", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public CompletableFuture<DataResult> deleteDevFromRoom(@RequestBody DeveleDeviceVo deviceVo) {
        return CompletableFuture.supplyAsync(() -> {
            logger.info("手机端-删除房间设备传入参数是->" + deviceVo);
            String realDid = deviceVo.getRealDid();
            JSONArray realDidArray = new JSONArray();
            realDidArray.add(realDid);
            Long controlId = deviceVo.getControlId();
            Long roomId = deviceVo.getRoomId();
            MIHomeUtil.deleteDevFromRoom(controlId, roomId, realDidArray.toJSONString());
            JSONArray roomList = MIHomeUtil.getHome(controlId).getJSONArray("homeInfo").getJSONObject(0).getJSONArray("roomlist");
            cacheComponent.putForExpire(Constant.PREFIX_CONTROL_HOME_ID, String.valueOf(controlId), roomList, 2592000);
            return DataResult.ok("删除成功");
        });
    }


    /**
     * 手机端-扫码电视登录
     *
     * @param queryTVVo
     * @return
     */
    @PostMapping("/tv/login")
    @ApiOperation(value = "电视登录", notes = "电视登录", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public CompletableFuture<DataResult> tvLogin(@RequestBody QueryTVVo queryTVVo) {
        return CompletableFuture.supplyAsync(() -> {
            logger.info("手机端-扫码电视登录参数={}", queryTVVo);
            Long controlUnitId = queryTVVo.getControlId();
            String data = queryTVVo.getData();
            String tvLoginResult = MIDeviceUtil.tvLogin(controlUnitId, data);
            if (StringUtils.isEmpty(tvLoginResult)) {
                return DataResult.error("扫描小米电视二维码超时，请重试");
            }
            String html = StringEscapeUtils.unescapeHtml(tvLoginResult);
            html.replaceAll("\n", "");
            return DataResult.ok().put("data", html);
        });
    }


    /**
     * 手机端-设备添加/修改接口
     *
     * @param query
     * @return
     */
    @PostMapping("/insertOrUpdate")
    @ApiOperation(value = "设备添加/修改接口", notes = "设备添加修改接口", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public CompletableFuture<DataResult> insertOrUpdate(@RequestBody QueryByControlIdVo query) {
        return CompletableFuture.supplyAsync(() -> {
            logger.info("手机端-设备添加/修改接口传入参数是->" + query);
            Long controlId = query.getControlId();
            JSONArray deviceList = MIDeviceUtil.getDeviceList(controlId);
            if (deviceList.size() == 0) {
                return DataResult.error("此房间无设备列表");
            }
            return DataResult.ok("保存成功");
        });
    }

    /**
     * 手机端-设备批量解绑
     *
     * @param query
     * @return
     */
    @PostMapping("/batchUnbound")
    @ApiOperation(value = "批量解绑设备", notes = "批量解绑设备", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public CompletableFuture<DataResult> batchUnbound(@RequestBody QueryByControlIdVo query) {
        return CompletableFuture.supplyAsync(() -> {
            logger.info("手机端-解绑设备传入参数是->" + query);
            Long controlId = query.getControlId();
            JSONArray deviceList = MIDeviceUtil.getDeviceList(controlId);
            for (int i = 0; i < deviceList.size(); i++) {
                JSONObject device = deviceList.getJSONObject(i);
                String realDid = device.getString("real_did");
                MIDeviceUtil.unbound(controlId, realDid);
            }
            return DataResult.ok("设备解绑成功");
        });
    }

    /**
     * 小米接口-获取设备列表
     *
     * @param params
     * @return
     */
    @PostMapping("/list")
    @ApiOperation(value = "获取设备列表", notes = "获取设备列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONArray getDeviceList(@RequestBody JSONObject params) {
        Long controlUnitId = params.getLong("controlUnitId");
        JSONArray deviceList = MIDeviceUtil.getDeviceList(controlUnitId);
        return deviceList;
    }

    /**
     * 小米接口-设置设备属性
     *
     * @param params
     * @return
     */
    @PostMapping("/set/properties")
    @ApiOperation(value = "设置设备属性", notes = "设置设备属性", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setProperties(@RequestBody JSONObject params) {
        String setProperties = MIDeviceUtil.setProperties(params.getJSONArray("properties"), params.getLong("controlUnitId"));
        return setProperties;
    }

    /**
     * 小米接口-根据类型获取属性
     *
     * @param params
     * @return
     */
    @PostMapping("/get/properties")
    public JSONObject getPropertiesByType(@RequestBody JSONObject params) {
        JSONObject properties = MIDeviceUtil.getPropertiesByType(params.getString("type"));
        logger.info("小米接口-根据类型获取属性={}", properties);
        return properties;
    }

    /**
     * 小米接口-设备解绑
     *
     * @param params
     */
    @PostMapping("/unbound")
    public void unbound(@RequestBody JSONObject params) {
        logger.info("小米接口解绑设备->",params);
        Long controlUnitId = params.getLong("controlUnitId");
        String realDid = params.getString("real_did");
        MIDeviceUtil.unbound(controlUnitId, realDid);
    }

}
